package com.example.abc.config;


import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;

/**
 * Created by Peter on 2018/4/28.
 */
public class AjaxAwareAuthEntryPointWrapper extends LoginUrlAuthenticationEntryPoint {
    // http://getstatuscode.com/440
    private static final int TIMEOUT_ERROR_CODE = 440;

    /**
     * @param loginFormUrl URL where the login page can be found. Should either be
     *                     relative to the web-app context path (include a leading {@code /}) or an absolute
     *                     URL.
     */
    public AjaxAwareAuthEntryPointWrapper(String loginFormUrl) {
        super(loginFormUrl);
    }


    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        HttpServletResponse proxyRes = response;

        // For an Ajax request use a RS wrapper to intercept the 302 and make it a 4xx
        String reqWith = request.getHeader("X-Requested-With");
        if (reqWith != null && reqWith.equals("XMLHttpRequest")) {

            // if the Request arrived here with a session id but no valid session then assume the session has timed out
            boolean hasSessionTimedOut = request.getRequestedSessionId() != null && !request.getRequestedSessionId().isEmpty() &&
                    (request.getSession(false) == null || request.getSession(false).isNew());
            final int errorCode = hasSessionTimedOut ? TIMEOUT_ERROR_CODE : HttpServletResponse.SC_UNAUTHORIZED;

            proxyRes = new HttpServletResponseWrapper(response) {

                private HttpServletResponse _getHttpServletResponse() {
                    return (HttpServletResponse) super.getResponse();
                }

                @Override
                public void sendRedirect(String location) throws IOException {
                    this._getHttpServletResponse().setHeader("Location", location);
                    this._getHttpServletResponse().sendError(errorCode);
                }
            };
        }

        super.commence(request, proxyRes, authException);
    }
}